package middleware

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"path"
	"strings"
)

const (
	staticPathPrefix   = "/static/"
	cacheControlHeader = "Cache-Control"
	cacheControlValue  = "public, max-age=2592000" // 缓存一个月
	eTagHeader         = "ETag"
	ifNoneMatchHeader  = "If-None-Match"
)

// CacheMiddleware 是一个中间件，用于设置缓存控制头
func CacheMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		if strings.HasPrefix(c.Request.URL.Path, staticPathPrefix) {
			// 设置缓存控制头
			c.Header(cacheControlHeader, cacheControlValue)

			// 生成并设置 ETag 头
			eTag := generateETag(c.Request.URL.Path)
			c.Header(eTagHeader, eTag)

			//检查 If-None-Match 头与生成的 ETag 是否匹配，若匹配则返回 304 Not Modified
			if match := c.GetHeader(ifNoneMatchHeader); match != "" {
				if match == eTag {
					log.Printf("Cache hit for: %s", c.Request.URL.Path)
					c.Status(http.StatusNotModified)
					c.Abort()
					return
				}
			}
		}
		c.Next()
	}
}

// generateETag 根据文件路径生成一个简单的 ETag
func generateETag(urlPath string) string {
	h := sha1.New()
	filePath := path.Join("/app", urlPath)
	_, err := h.Write([]byte(filePath)) // 这里只是为了示例，实际可以基于文件内容
	if err != nil {
		log.Printf("Error generating ETag for %s: %v", filePath, err)
		return ""
	}
	return fmt.Sprintf("\"%s\"", hex.EncodeToString(h.Sum(nil)))
}
